package com.stox.indicator;

import java.util.List;

import lombok.Data;

import org.springframework.stereotype.Component;

import com.stox.dto.Bar;
import com.stox.indicator.VolumeByPrice.Configuration;
import com.stox.indicator.VolumeByPrice.Unit;

@Component
public class VolumeByPrice implements Overlay<Configuration, Unit> {
	
	@Data
	public static class Unit{
		private double upVolume;
		private double downVolume;
	}
	
	@Data
	public static class Configuration{
		private int divisions = 30;
	}

	@Override
	public Configuration createDefaultConfiguration() {
		return new Configuration();
	}

	@Override
	public Unit getValue(Configuration configuration, List<Bar> bars, int index) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public Double[] getValues(Configuration configuration, Double[] values){
		throw new UnsupportedOperationException();
	}

	@Override
	public Unit[] getValues(Configuration configuration, List<Bar> bars) {
		double min = Double.MAX_VALUE;
		double max = Double.MIN_VALUE;
		Unit[] units = new Unit[configuration.getDivisions()];
		
		for(Bar bar : bars){
			if(min > bar.getLow()){
				min = bar.getLow();
			}
			if(max < bar.getHigh()){
				max = bar.getHigh();
			}
		}
		double range = (max - min)/configuration.getDivisions();
		for(int i = bars.size() - 1; i >= 0; i--){
			Bar bar = bars.get(i);
			int unitIndex = (int)((bar.getClose() - min)/range);
			if(unitIndex == configuration.getDivisions())
				unitIndex--;
			Unit unit = units[unitIndex];
			if(null == unit){
				unit = new Unit();
				units[unitIndex] = unit;
			}
			
			if(i == bars.size() - 1){
				unit.setDownVolume(bar.getVolume()/2);
				unit.setUpVolume(bar.getVolume()/2);
				continue;
			}else{
				Bar previousBar = bars.get(i + 1);
				if(previousBar.getClose() > bar.getClose()){
					unit.setDownVolume(unit.getDownVolume() + bar.getVolume());
				}else{
					unit.setUpVolume(unit.getUpVolume() + bar.getVolume());
				}
			}
		}
		Unit filler = new Unit();
		for(int index = 0; index < units.length; index++){
			if(null == units[index]){
				units[index] = filler;
			}
		}
		return units;
	}
	
	

}
